
/* tpm2_crypt_rand.h */
/* 10.1.4.1 Introduction */
/* This file contains constant definition shared by CryptUtil() and the parts of the Crypto
   Engine. */
#ifndef _CRYPT_RAND_H
#define _CRYPT_RAND_H
/* DRBG Structures and Defines Values and structures for the random number generator. These values
   are defined in this header file so that the size of the RNG state can be known to TPM.lib. This
   allows the allocation of some space in NV memory for the state to be stored on an orderly
   shutdown. The DRBG based on a symmetric block cipher is defined by three values, */
/* a) the key size */
/* b) the block size (the IV size) */
/* c) the symmetric algorithm */
#ifndef RADIX_BITS
#   if defined(__x86_64__) || defined(__x86_64)				\
    || defined(__amd64__) || defined(__amd64) || defined(_WIN64) || defined(_M_X64) \
    || defined(_M_ARM64) || defined(__aarch64__) \
    || defined(__powerpc64__) || defined(__ppc64__)
#       define RADIX_BITS                      64
#   elif defined(__i386__) || defined(__i386) || defined(i386)		\
    || defined(_WIN32) || defined(_M_IX86)				\
    || defined(_M_ARM) || defined(__arm__) || defined(__thumb__)
#       define RADIX_BITS                      32
#   else
#       error Unable to determine RADIX_BITS from compiler environment
#   endif

#endif // RADIX_BITS
#ifndef RADIX_BYTES
#   if RADIX_BITS == 32
#       define RADIX_BYTES 4
#   elif RADIX_BITS == 64
#       define RADIX_BYTES 8
#   else
// #       error "RADIX_BITS must either be 32 or 64"
#   endif
#endif

#if RADIX_BITS == 64
# define RADIX_LOG2         6
#elif RADIX_BITS == 32
#define RADIX_LOG2          5
// #else
// # error "Unsupported radix"
#endif
#define RADIX_MOD(x)        ((x) & ((1 << RADIX_LOG2) - 1))
#define RADIX_DIV(x)        ((x) >> RADIX_LOG2)
#define RADIX_MASK  ((((crypt_uword_t)1) << RADIX_LOG2) - 1)
#define BITS_TO_CRYPT_WORDS(bits)       RADIX_DIV((bits) + (RADIX_BITS - 1))
#define BYTES_TO_CRYPT_WORDS(bytes)     BITS_TO_CRYPT_WORDS(bytes * 8)
#define SIZE_IN_CRYPT_WORDS(thing)      BYTES_TO_CRYPT_WORDS(sizeof(thing))
#if RADIX_BITS == 64
// #define SWAP_CRYPT_WORD(x)  REVERSE_ENDIAN_64(x)
/* Unsigned.  */
typedef unsigned char		uint8_t;
typedef unsigned short int	uint16_t;
#ifndef __uint32_t_defined
typedef unsigned int		uint32_t;
# define __uint32_t_defined
#endif
#if __WORDSIZE == 64
typedef unsigned long int	uint64_t;
#else
__extension__
typedef unsigned long long int	uint64_t;
#endif
typedef uint64_t    crypt_uword_t;
typedef int64_t     crypt_word_t;
#   define TO_CRYPT_WORD_64             BIG_ENDIAN_BYTES_TO_UINT64
#   define TO_CRYPT_WORD_32(a, b, c, d) TO_CRYPT_WORD_64(0, 0, 0, 0, a, b, c, d)
#elif RADIX_BITS == 32
// #define SWAP_CRYPT_WORD(x)  REVERSE_ENDIAN_32((x))
typedef uint32_t    crypt_uword_t;
typedef int32_t     crypt_word_t;
#   define TO_CRYPT_WORD_64(a, b, c, d, e, f, g, h)			\
    BIG_ENDIAN_BYTES_TO_UINT32(e, f, g, h),				\
    BIG_ENDIAN_BYTES_TO_UINT32(a, b, c, d)
#  define TO_CRYPT_WORD_32 		BIG_ENDIAN_BYTES_TO_UINT32
#endif
#define MAX_CRYPT_UWORD (~((crypt_uword_t)0))
#define MAX_CRYPT_WORD  ((crypt_word_t)(MAX_CRYPT_UWORD >> 1))
#define MIN_CRYPT_WORD  (~MAX_CRYPT_WORD)
#define LARGEST_NUMBER (MAX((ALG_RSA * MAX_RSA_KEY_BYTES),		\
			    MAX((ALG_ECC * MAX_ECC_KEY_BYTES), MAX_DIGEST_SIZE)))
#define LARGEST_NUMBER_BITS (LARGEST_NUMBER * 8)
#define MAX_ECC_PARAMETER_BYTES (MAX_ECC_KEY_BYTES * ALG_ECC)
#define DRBG_KEY_SIZE_BITS  256

/*     Derived values */
// #define DRBG_MAX_REQUESTS_PER_RESEED (1 << 48)
// #define DRBG_MAX_REQEST_SIZE (1 << 32)
#define pDRBG_KEY(seed)    ((DRBG_KEY *)&(((BYTE *)(seed))[0]))
#define pDRBG_IV(seed)     ((DRBG_IV *)&(((BYTE *)(seed))[DRBG_KEY_SIZE_BYTES]))
#define DRBG_KEY_SIZE_WORDS     (BITS_TO_CRYPT_WORDS(DRBG_KEY_SIZE_BITS))
#define DRBG_KEY_SIZE_BYTES     (DRBG_KEY_SIZE_WORDS * RADIX_BYTES)
#define DRBG_IV_SIZE_WORDS      (BITS_TO_CRYPT_WORDS(DRBG_IV_SIZE_BITS))
#define DRBG_IV_SIZE_BYTES      (DRBG_IV_SIZE_WORDS * RADIX_BYTES)
#define DRBG_SEED_SIZE_WORDS    (DRBG_KEY_SIZE_WORDS + DRBG_IV_SIZE_WORDS)
#define DRBG_SEED_SIZE_BYTES    (DRBG_KEY_SIZE_BYTES + DRBG_IV_SIZE_BYTES)
// typedef UINT32    crypt_uword_t;

// #define DRBG_KEY_SIZE_BITS      AES_MAX_KEY_SIZE_BITS
#define DRBG_IV_SIZE_BITS       (AES_MAX_BLOCK_SIZE * 8)
#define DRBG_ALGORITHM          TPM_ALG_AES

// 注释： 由于 未知类型名 tpmKeyScheduleAES 
typedef tpmKeyScheduleAES DRBG_KEY_SCHEDULE;

#define DRBG_ENCRYPT_SETUP(key, keySizeInBits, schedule)		\
    TpmCryptSetEncryptKeyAES(key, keySizeInBits, schedule)
#define DRBG_ENCRYPT(keySchedule, in, out)				\
    TpmCryptEncryptAES(SWIZZLE(keySchedule, in, out))

// 注释：由于 #if 中用零做参数 ，
// #if     ((DRBG_KEY_SIZE_BITS % RADIX_BITS) != 0)	\
//     || ((DRBG_IV_SIZE_BITS % RADIX_BITS) != 0)
// #error "Key size and IV for DRBG must be even multiples of the radix"
// #endif
// #if (DRBG_KEY_SIZE_BITS % DRBG_IV_SIZE_BITS) != 0
// #error "Key size for DRBG must be even multiple of the cypher block size"
// #endif



//TODO: 删除union
typedef union
{
    BYTE            bytes[DRBG_KEY_SIZE_BYTES];
    crypt_uword_t   words[DRBG_KEY_SIZE_WORDS];
} DRBG_KEY;
typedef union
{
    BYTE            bytes[DRBG_IV_SIZE_BYTES];
    crypt_uword_t   words[DRBG_IV_SIZE_WORDS];
} DRBG_IV;
typedef union
{
    BYTE            bytes[DRBG_SEED_SIZE_BYTES];
    crypt_uword_t   words[DRBG_SEED_SIZE_WORDS];
} DRBG_SEED;
// typedef struct
// {
//     BYTE            bytes[DRBG_KEY_SIZE_BYTES];
// } DRBG_KEY;
// typedef struct
// {
//     BYTE            bytes[DRBG_IV_SIZE_BYTES];
// } DRBG_IV;
// typedef struct
// {
//     BYTE            bytes[DRBG_SEED_SIZE_BYTES];
// } DRBG_SEED;

typedef struct
{
    UINT32      rng;
    UINT32      hash;
    UINT32      sym;
#if ALG_ECC
    UINT32      ecc;
#endif
} CRYPTO_SELF_TEST_STATE;

// 5.9.14	From CryptTest.c
// This structure contains the self-test state values for the cryptographic modules.
CRYPTO_SELF_TEST_STATE   g_cryptoSelfTestState;

#define CTR_DRBG_MAX_REQUESTS_PER_RESEED        ((UINT64)1 << 20)
#define CTR_DRBG_MAX_BYTES_PER_REQUEST          (1 << 16)
#   define CTR_DRBG_MIN_ENTROPY_INPUT_LENGTH    DRBG_SEED_SIZE_BYTES
#   define CTR_DRBG_MAX_ENTROPY_INPUT_LENGTH    DRBG_SEED_SIZE_BYTES
#   define CTR_DRBG_MAX_ADDITIONAL_INPUT_LENGTH DRBG_SEED_SIZE_BYTES
#define     TESTING         (1 << 0)
#define     ENTROPY         (1 << 1)
#define     TESTED          (1 << 2)
#define     IsTestStateSet(BIT)    ((g_cryptoSelfTestState.rng & BIT) != 0)
#define     SetTestStateBit(BIT)   (g_cryptoSelfTestState.rng |= BIT)
#define     ClearTestStateBit(BIT) (g_cryptoSelfTestState.rng &= ~BIT)
#define     IsSelfTest()    IsTestStateSet(TESTING)
#define     SetSelfTest()   SetTestStateBit(TESTING)
#define     ClearSelfTest() ClearTestStateBit(TESTING)
#define     IsEntropyBad()      IsTestStateSet(ENTROPY)
#define     SetEntropyBad()     SetTestStateBit(ENTROPY)
#define     ClearEntropyBad()   ClearTestStateBit(ENTROPY)
#define     IsDrbgTested()      IsTestStateSet(TESTED)
#define     SetDrbgTested()     SetTestStateBit(TESTED)
#define     ClearDrbgTested()   ClearTestStateBit(TESTED)

typedef struct
    {
	UINT64      reseedCounter;
	UINT32      magic;
	DRBG_SEED   seed; // contains the key and IV for the counter mode DRBG
	UINT32      lastValue[4];   // used when the TPM does continuous self-test for FIPS compliance of DRBG
    } DRBG_STATE, *pDRBG_STATE;
#define DRBG_MAGIC   ((UINT32) 0x47425244) // "DRBG" backwards so that it displays
typedef struct
{
    UINT64               counter; // 调用者可以为增量操作提供迭代计数器，以避免大型中间缓冲区。
    UINT32               magic;
    UINT32               limit;
    TPM2B               *seed;
    const TPM2B         *label;
    TPM2B               *context;
    TPM_ALG_ID           hash;
    TPM_ALG_ID           kdf;
    UINT16               digestSize;
    TPM2B_DIGEST         residual;
} KDF_STATE, *pKDR_STATE;
#define KDF_MAGIC    ((UINT32) 0x4048444a) // "KDF " backwards
/* Make sure that any other structures added to this union start with a 64-bit counter and a 32-bit
   magic number */
// TODO: 去除union. 
// DRBG  Deterministic Random Bit Generator 
// KDF  key derivation function
// RNG  Random Number Generator 
// 12.1 TPM2_Create 
// The methods in this clause are used by both TPM2_Create() and TPM2_CreatePrimary(). When a value 
// is indicated as being TPM-generated, the value is filled in by bits from the RNG if the command is 
// TPM2_Create() and with values from KDFa() if the command is TPM2_CreatePrimary(). The parameters 
// of each creation value are specified in TPM 2.0 Part 1.

typedef union
{
    DRBG_STATE      drbg;
    KDF_STATE       kdf;
} RAND_STATE;

// 修改union为struct，去除变量DRBG_STATE，将RAND_STATE只用于KDF_STATE
// typedef struct
// {
//     KDF_STATE       kdf;
// } RAND_STATE;
/* This is the state used when the library uses a random number generator. A special function is
   installed for the library to call. That function picks up the state from this location and uses
   it for the generation of the random number. */
/* 这是当库使用随机数发生器时使用的状态。我们安装了一个特殊的函数供库调用。
该函数从这个位置获取状态，并将其用于生成随机数。*/
extern RAND_STATE           *s_random;
/* When instrumenting RSA key sieve */
#if  RSA_INSTRUMENT
#define PRIME_INDEX(x)  ((x) == 512 ? 0 : (x) == 1024 ? 1 : 2)
#   define INSTRUMENT_SET(a, b) ((a) = (b))
#   define INSTRUMENT_ADD(a, b) (a) = (a) + (b)
#   define INSTRUMENT_INC(a)    (a) = (a) + 1
extern UINT32  PrimeIndex;
extern UINT32  failedAtIteration[10];
extern UINT32  PrimeCounts[3];
extern UINT32  MillerRabinTrials[3];
extern UINT32  totalFieldsSieved[3];
extern UINT32  bitsInFieldAfterSieve[3];
extern UINT32  emptyFieldsSieved[3];
extern UINT32  noPrimeFields[3];
extern UINT32  primesChecked[3];
extern UINT16  lastSievePrime;
#else
#   define INSTRUMENT_SET(a, b)
#   define INSTRUMENT_ADD(a, b)
#   define INSTRUMENT_INC(a)
#endif
#endif // _CRYPT_RAND_H

